package com.imyuanma.qingyun.common.config.security;

import com.imyuanma.qingyun.common.client.ums.LoginUserHolder;
import com.imyuanma.qingyun.common.util.StringUtil;
import com.imyuanma.qingyun.interfaces.ums.model.LoginUserDTO;
import com.imyuanma.qingyun.interfaces.ums.service.IUmsPermissionsOutService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

/**
 * 注销登录成功处理
 *
 * @author wangjy
 * @date 2022/08/15 23:09:12
 */
@Component
public class DefaultLogoutSuccessHandler implements LogoutSuccessHandler {
    private static final Logger logger = LoggerFactory.getLogger(DefaultLogoutSuccessHandler.class);
    /**
     * 权限服务
     */
    @Autowired
    private IUmsPermissionsOutService permissionsOutService;

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        // 注销成功后的重定向地址, 一般情况下重定向到登录页, 有特殊的就传redirectTo
        String redirectTo = request.getParameter("redirectTo");
        if (StringUtil.isBlank(redirectTo)) {
            redirectTo = "/page/login.html";
        }

        // 退出登录来自于哪个url
        // 例如访问a页面,此时由于会话失效而被ums拦截器重定向到注销请求(或者登陆页),重定向时会在链接中携带上链接a,用来在将来登陆成功后直接跳转a页面
        String fromUrl = request.getParameter("fromUrl");
        if (StringUtil.isNotBlank(fromUrl) && !fromUrl.startsWith(redirectTo) && !"/sso/logout".equals(fromUrl)) {
            redirectTo += redirectTo.indexOf("?") > 0 ? "&" : "?" + "fromUrl=" + URLEncoder.encode(fromUrl, "UTF-8");
        }

        // 当前用户
        LoginUserDTO loginUserDTO = LoginUserHolder.getLoginUser();
        if (loginUserDTO != null) {
            logger.info("[注销登录] {}[ID:{},账号:{}]注销登录,重定向地址:{}", loginUserDTO.getName(), loginUserDTO.getUserId(), loginUserDTO.getAccount(), redirectTo);
        } else {
            logger.info("[注销登录] 当前会话不存在用户信息,重定向地址:{}", redirectTo);
        }

        try {
            if (authentication != null && authentication.getPrincipal() instanceof DefaultUserDetails) {
                DefaultUserDetails userDetails = (DefaultUserDetails) authentication.getPrincipal();
                if (userDetails != null && StringUtil.isNotBlank(userDetails.getToken())) {
                    // 下线会话
                    permissionsOutService.offlineSession(userDetails.getToken());
                }
            }
        } catch (Throwable t) {
            logger.error("[注销登录] 下线会话时发生异常", t);
        }

        // 清除cookie的token信息
        Cookie cookie = new Cookie(SecurityConstants.TOKEN_KEY, null);
        cookie.setMaxAge(0);
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        response.addCookie(cookie);

        // 重定向
        response.sendRedirect(redirectTo);
    }
}
